#ifndef JOUEUR_H
#define JOUEUR_H

#include "ADD.h"
using namespace std;

enum TypeMulti {Non, Mul, Jum};
enum TypeComp  {Don, Desav};

void OutputLevel();

class Joueur
{
 public:
  /****************************************************************************
   *
   * Constructeurs
   * Le constructeur par défaut fait appel au chargement d'un Joueur depuis
   * un fichier .xml
   * L'autre constructeur sert lors de la création d'un nouveau Joueur
   *
   ***************************************************************************/
  Joueur();
  Joueur(Classe* classe, Race* race, const string& nom);
  /****************************************************************************
   *
   * Destructeur
   * Le destructeur gère la libération de la mémoire allouée
   *
   ***************************************************************************/
  ~Joueur();
  /****************************************************************************
   *
   * Méthodes
   *
   ***************************************************************************/
  void info();
  // Affiche le nom, la race et la (les) classes
  string demander_nom() const;
  // Demande à l'utilisateur d'entrer le nom du fichier à ouvrir
  void ecrire_xml() const;
  // Sauve le Joueur dans un fichier .xml
  void set_pp(const unsigned int& pps);
  // Permet de fixer le nombre de pp
  void set_pv(const unsigned int& pv);
  // Permet de fixer le nombre de pv
  void ajout_classe(Classe* classe);
  // Permet d'ajouter une classe
  void ecrire_tex() const;
  // Prépare la sortie en .tex
  unsigned int get_combien_dons() const;
  unsigned int get_combien_desavantages() const;
  unsigned int get_combien_competences() const;
  unsigned int get_combien_comp_martiales() const;
  // Renvoie le nbr de dons, désavantages ou compétences (non) martiales
  static void setLevel(const DebugLevelType& level, const unsigned int& n);
  // Fixe les niveaux de sortie des différentes méthodes
  string a_sorts_mage(vector<Classe *>& vec) const;
  /*
   * Regarde si le Joueur possède des sorts de mage (=> mage, spécialiste,
   * barde avec compétence) et remplit vec avec les pointeurs sur les classe
   * possédant de tels sorts
  */

  /****************************************************************************
   *
   * Fonctions de gestion de l'évolution du Joueur
   *
   ***************************************************************************/
  void determiner_dons_desavantages(const TypeComp& quoi);
  void determiner_competences();
  void augmenter_competences();
  void determiner_comp_martiales();
  void ajouter_xp(const unsigned int& xp);
  void ajouter_pp(const unsigned int& pp);
  void ajouter_pv(const unsigned int& pv);

 protected:
  string Nom;
  // Nom du Joueur
  vector<Classe*> J_classe;
  // Classe(s)
  Race* J_race;
  // Race
  unsigned int TAc0, PV, PP, nb_classes;
  int CA;
  // Nbr de classes, dimension de J_classe
  vector<unsigned int> J_CompDiv, J_Dons, J_Desavantages, J_Martiales;

  /****************************************************************************
   *
   * Niveaux de sortie des sous-fonctions
   * 'static', toujours par soucis d'optimisation
   *
   ***************************************************************************/

  static DebugLevelType fonction_elementaire_xml;
  static DebugLevelType fonction_recuperation_xml;
  static DebugLevelType fonction_tex;
  static DebugLevelType interne;

 private:
  /****************************************************************************
   *
   * Ajustements dus aux traits, sont stockés sous forme de tableaux 'static'
   * par soucis d'optimisation.
   *
   ***************************************************************************/
  static const string Aj_Force[30][6];
  static const string Aj_Dexterite[14][3];
  static const string Aj_Const[25][5];
  static const string Aj_Int[19][5];
  static const string Aj_Sagesse[24][4];
  static const string Aj_Charisme[24][3];

  /****************************************************************************
   *
   * Dons, désavantages et compétences non-martiales
   * 'static', toujours par soucis d'optimisation
   *
   ***************************************************************************/

  static const ListCapa Dons[27], Desavantages[38];

  static const ListNonMart CompetencesDiverses[85];

  bool libere_mem;
  // Gestion de la mémoire allouée dynamiquement
  TypeMulti TM_switch;
  // Gestion de multiclassé ou classes jumelées (=> gestion des XPs)
  void modificateur_PP();
  // Modifie les PP alloués au Joueur, selon son score
  void modificateur_val(unsigned int& val, const unsigned int& trait);
  // Ajuste la valeur d'une compétence en fonction du trait


  /****************************************************************************
   *
   * Sous-fonctions qui écrivent les différentes parties du code .tex
   * nécessaire pour la feuille complète.
   *
   ***************************************************************************/
  void ecrire_traits_tex() const;
  void ecrire_JS_tex() const;
  void ecrire_scores_tex() const;
  void ecrire_race_tex() const;
  void ecrire_classe_tex() const;
  void ecrire_comp_tex() const;
  void ecrire_sorts_tex() const;


  /****************************************************************************
   *
   * Fonctions XML
   *
   ***************************************************************************/
  int index;
  // Position de lecture du fichier .xml
  void trouver_o (string&);
  // Cherche le caractere <, en fonction de la derniere position de lecture
  void trouver_f (string&);
  // Cherche le caractère >, en fonction de la derniere position de lecture (?)
  int trouver_o_I (string&);
  // Cherche le caractere > qui indique la fin d une balise
  int trouver_f_I (string&);
  // Cherche le caractere > qui indique la fin d une balise
  void sauter_blanc(string&);
  // Avance l'index de lecture jusqu'au moment ou y a plus de blancs
  // (caractere vide)
  void wipe_blank(string& a);
  // Enlève les blancs ' ' à la fin d'une string
  string lit_balise(string&,char&);
  // Lit et renvoie le contenu d'une balise
  void skip_comment(string&);
  // Saute les parties commentées <!-- -->
  bool verifier_contenu_futur(string& a, string& b);
  // Lit le contenu de la prochaine balise et le compare avec la chaine b
  int read_int(string&);
  // Lit un int et le renvoie
  int translate(char);
  // Traduit un char en int
  bool c_un_chiffre(char);
  // Vérifie que l'on est bien en train de lire un caractère numérique

  /****************************************************************************
   *
   * Méthodes de récupérations des infos
   *
   ***************************************************************************/
  void trouver_interpreter_ecrire_joueur(string&);
  // Effectue la lecture du fichier .xml, écrit le Joueur
  void trouver_interpreter_ecrire_typeRace(string&);
  // Gestion de la Race du Joueur
  void trouver_interpreter_ecrire_typeClasse(string&, unsigned int tab[7]);
  // Gestion d'une Classe du Joueur

  string trouver_interpreter_ecrire_nom(string&);
  string trouver_interpreter_ecrire_race(string&);
  string trouver_interpreter_ecrire_classe(string&);
  // Retrouvent la string qui indique le Nom, la Race et la Classe

  void trouver_interpreter_ecrire_capacites(string&, vector<unsigned int>&);
  void trouver_interpreter_ecrire_traits(string&, unsigned int tab[7]);
  void trouver_interpreter_ecrire_competences(string&, vector<unsigned int>&);
  void trouver_interpreter_ecrire_dons(string&, vector<unsigned int>&);
  void trouver_interpreter_ecrire_desavantages(string&, vector<unsigned int>&);
  void trouver_interpreter_ecrire_nonmart(string&, vector<unsigned int>&);
  void trouver_interpreter_ecrire_martiales(string&, vector<unsigned int>&);
  void trouver_interpreter_ecrire_sorts(string&, vector<Sort>&);
  // Retrouvent les capacités raciales, les traits et les compétences
  // de classe et les sorts (de type mage)

  int trouver_interpreter_ecrire_nb(string&);
  int trouver_interpreter_ecrire_PV(string&);
  int trouver_interpreter_ecrire_PP(string&);
  int trouver_interpreter_ecrire_XP(string&);
  // Retrouvent le nombre de classe, le nbr de PV, de PP et les XP
};

#endif
